<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <link rel="stylesheet" href="../../public/css/bootstrap.min.css" />
        <link rel="stylesheet" href="../../public/css/xterm.min.css" />
        <link rel="stylesheet" href="../../public/css/theme.css" />
        <script src="../../components/icon-svg.js"></script>
        <script src="../../components/reconnect.js"></script>
        <script src="../../components/lepton.js"></script>
        <script src="../../public/js/vue/vue.global.prod.js"></script>
        <style>
            #app {
                font-size: 13px;
                gap: 16px;
                height: 100vh;
            }
        </style>
    </head>
    <body>
        <div id="app" class="d-flex">
            <div id="terminal" class="h-100 w-75 bg-black"></div>
            <!-- <div>
                <div class="" v-for="item in commandList">
                    <span>{{item}}</span>
                </div>
            </div> -->
            <div class="flex-fill flex-shrink-0 d-flex flex-column">
                <div class="overflow-auto max-vh-60">
                    <template v-for="item in helps" :key="item.name">
                        <div v-if="item.type == 'checkbox'" class="form-check mb-3">
                            <input
                                class="form-check-input"
                                :id="item.name"
                                :type="item.type"
                                :placeholder="item.placeholder"
                                v-model="item.defaultValue"
                                :required="item.required"
                                @change="onBuildCommand"
                                checked />
                            <label class="form-check-label">
                                {{item.label}}
                                <span class="required" v-if="item.required">(必须)</span>
                            </label>
                        </div>
                        <div v-else-if="item.type == 'radio'" class="form-check mb-3">
                            <input
                                class="form-check-input"
                                :id="item.name"
                                :type="item.type"
                                :placeholder="item.placeholder"
                                v-model="item.defaultValue"
                                :required="item.required"
                                @change="onBuildCommand"
                                checked />
                            <label class="form-check-label" for="radio1">
                                {{item.label}}
                                <span class="required" v-if="item.required">(必须)</span>
                            </label>
                        </div>
                        <div v-else-if="item.type == 'switch'" class="form-check form-switch mb-3">
                            <input
                                class="form-check-input"
                                :id="item.name"
                                :type="item.type"
                                :placeholder="item.placeholder"
                                v-model="item.defaultValue"
                                :required="item.required"
                                @change="onBuildCommand"
                                checked />
                            <label class="form-check-label" for="mySwitch">
                                {{item.label}}
                                <span class="required" v-if="item.required">(必须)</span>
                            </label>
                        </div>
                        <div v-else class="mb-3">
                            <label :for="item.name">
                                {{item.label}}
                                <span class="required" v-if="item.required">(必须)</span>
                            </label>
                            <input
                                :id="item.name"
                                class="form-control form-control-sm py-1 px-2 fs-inherit"
                                :type="item.type"
                                :placeholder="item.placeholder"
                                v-model="item.defaultValue"
                                @change="onBuildCommand"
                                :required="item.required" />
                        </div>
                    </template>
                </div>
                <textarea
                    class="flex-fill text-wrap"
                    placeholder="使用 Ctrl+Enter 或者 Shift+Enter 组合键执行命令"
                    v-model="command"
                    @keydown="onKeydown"></textarea>
                <button class="btn btn-primary btn-block mt-2 py-2" @click="onExecute">
                    提交命令
                </button>
            </div>
            <Reconnect></Reconnect>
        </div>
        <script src="../../public/js/xterm.js"></script>
        <script src="../../public/js/xterm.js"></script>
        <script src="../../public/js/addon-fit.js"></script>
        <script src="../../public/js/addon-canvas.js"></script>
        <script src="../../public/js/addon-web-links.js"></script>
        <script>
            const { createApp } = Vue
            const app = createApp({
                data() {
                    return {
                        terminal: null,
                        input: '',
                        commandList: [],
                        template: '',
                        command: '',
                        helps: []
                    }
                },
                mounted() {
                    this.initChannel()
                },
                methods: {
                    onInit() {
                        try {
                            this.terminal = new Terminal({
                                wrap: false
                            })
                            const fitAddon = new window.FitAddon.FitAddon()
                            const canvasAddon = new CanvasAddon.CanvasAddon()
                            const webLinks = new WebLinksAddon.WebLinksAddon()
                            this.terminal.loadAddon(fitAddon)
                            this.terminal.loadAddon(canvasAddon)
                            this.terminal.loadAddon(webLinks)
                            const node = document.getElementById('terminal')
                            this.terminal.open(node)
                            this.terminal.onData(data => {
                                this.onInput(data)
                            })
                            fitAddon.fit()
                            window.addEventListener('resize', () => {
                                fitAddon.fit()
                            })
                            this.onFn('onOpen')
                        } catch (error) {
                            this.onFn('onError', error)
                        }
                    },
                    saveCommand(command) {
                        this.commandList.push(command)
                        this.onFn('onSaveCommand', command)
                    },
                    onInput(data) {
                        if (data != '\r') {
                            this.input = this.input + data
                        } else {
                            let match = this.input.match(/(\\+)$/)
                            if (match) {
                                let suffix = match[1]
                                if (suffix.length % 2 == 0) {
                                    this.saveCommand(this.input)
                                    this.input = ''
                                } else {
                                    this.input = this.input.slice(0, -1) + '\n'
                                }
                            } else {
                                this.saveCommand(this.input)
                                this.input = ''
                            }
                        }
                        this.onFn('onExec', data)
                    },
                    onOutput(data) {
                        this.terminal.write(data)
                    },
                    onHelp({ template, helps }) {
                        this.template = template
                        this.helps = helps
                        this.onBuildCommand()
                    },

                    onBuildCommand() {
                        const value = {}
                        this.helps.forEach(it => {
                            if (it.defaultValue) {
                                if (it.isSingle) {
                                    value[it.name] = it.defaultValue
                                } else {
                                    value[it.name] = '--' + it.name + '=' + it.defaultValue
                                }
                            }
                        })
                        this.command = this.template.replace(
                            /\{([\w-]+)\}/g,
                            (match, key) => value[key] || ''
                        )
                    },
                    onExecute() {
                        const comm = this.command.replace(/(\r?\n)+$/, '') + '\n'
                        this.onFn('onExec', comm)
                    },
                    onKeydown(event) {
                        if (event.ctrlKey && event.key === 'Enter') {
                            event.preventDefault()
                            this.onExecute()
                        } else if (event.shiftKey && event.key === 'Enter') {
                            event.preventDefault()
                            this.onExecute()
                            this.command = ''
                        }
                    }
                }
            })
            app.use(window.lepton)
            app.mount('#app')
        </script>
    </body>
</html>
